package com.tarena.lbs.coupon.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import com.tarena.lbs.coupon.dao.repository.CouponRepository;
import com.tarena.lbs.coupon.pojo.param.CouponParam;
import com.tarena.lbs.coupon.pojo.po.CouponPO;
import com.tarena.lbs.coupon.pojo.query.CouponQuery;
import com.tarena.lbs.coupon.pojo.vo.CouponVO;
import com.tarena.lbs.coupon.service.CouponService;
import com.tarena.lbs.user.api.UserApi;
import com.tarena.lbs.user.api.pojo.dto.AdminDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * ===============================================
 * class: CouponServiceImpl
 * author: HanChao
 * date: 2025/9/1 10:23
 * DESCRIPTION: TODO (填写类的作用)
 * ===============================================
 */
@Service
@Slf4j
public class CouponServiceImpl implements CouponService {
    @Autowired
    private CouponRepository couponRepository;
    @DubboReference
    private UserApi userApi;

    /*
    * 优惠券详情
    * */
    @Override
    public CouponVO detail(Integer id) {
        log.info("查询优惠券详情入参:{}",id);
        CouponPO couponPO = couponRepository.getCouponById(id);
        CouponVO couponVO = null;
        if (couponPO != null){
            couponVO= new CouponVO();
            BeanUtils.copyProperties(couponPO,couponVO);
        }
        return couponVO;
    }

    /*
    * 优惠券列表分页查询
    * */
    @Override
    public PageResult<CouponVO> pageList(CouponQuery query) {




        log.info("查询优惠券列表，入参:{}",query);
        AdminDto adminById = userApi.getAdminById(AuthenticationContextUtils.get().getId());
        log.info("查询优惠券列表入参:{}",query);
        if (adminById==null){
            throw new RuntimeException("商家不存在");
        }
        query.setBusinessId(adminById.getBusinessId());
        log.info("查询优惠券列表入参:{}",query);
        PageResult<CouponVO> voPage = new PageResult<>();
        PageInfo<CouponPO> pageInfo = couponRepository.pageList(query);
        voPage.setPageNo(pageInfo.getPageNum());
        voPage.setPageSize(pageInfo.getPageSize());
        voPage.setTotal(pageInfo.getTotal());
        List<CouponVO> vos = null;
        List<CouponPO> pos = pageInfo.getList();
        if (CollectionUtils.isNotEmpty(pos)){
            vos=pos.stream().map(po->{
                CouponVO vo = new CouponVO();
                BeanUtils.copyProperties(po,vo);
                return vo;
            }).collect(Collectors.toList());
        }
        voPage.setObjects(vos);
        return voPage;
    }

    /*
    * 删除优惠券
    * */
    @Override
    public void delete(Integer id) {
        log.info("删除优惠券入参:{}",id);
        couponRepository.delete(id);
        log.info("删除优惠券成功");
    }

    /*
    * 修改启用状态
    * */
    @Override
    public void updateStatus(Integer id, Integer enableStatus) {
        log.info("更新优惠券状态入参:{},{}",id,enableStatus);
        couponRepository.updateStatus(id,enableStatus);
    }

    /*
    * 修改优惠券
    * */
    @Override
    public void updateCoupon(CouponParam couponParam) {
        log.info("修改优惠券入参:{}",couponParam);
        //转换startDate和endDate的格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 设置严格解析模式，避免不合法的日期被解析（如2023-13-01）
        sdf.setLenient(false);
        Date startDate = null;
        Date endDate= null;
        try {
            startDate = sdf.parse(couponParam.getStartDate());
            endDate = sdf.parse(couponParam.getEndDate());
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        CouponPO couponPO=new CouponPO();
        AdminDto adminDto=userApi.getAdminById(AuthenticationContextUtils.get().getId());
        couponParam.setBusinessId(adminDto.getBusinessId());
        BeanUtils.copyProperties(couponParam,couponPO);
        couponPO.setStartDate(startDate);
        couponPO.setEndDate(endDate);
        couponPO.setUpdateAt(new Date());
        log.info("实体类参数:{}",couponPO);

        if (couponParam.getId()==null){
            //新增
            couponPO.setCreateAt(new Date());
            int status=getCouponStatus(startDate,endDate);
            couponPO.setStatus(status);
            couponPO.setEnableStatus(1);
            log.info("新增优惠券数据层入参:{}",couponPO);
            couponRepository.saveCoupon(couponPO);
        }else {
            //修改
            couponRepository.updateCoupon(couponPO);
        }
    }

    //定时任务,每天更新优惠券状态
    @Scheduled(cron = "0 0 0 * * ?") //注解改为"0 * * * * ?"即可每分钟查询
    public void updateCouponStatusDay(){
        log.info("定时任务开始执行：更新优惠券状态");
        List<CouponPO> allCoupons = couponRepository.findAll();
        if (CollectionUtils.isEmpty(allCoupons)) {
            log.info("没有需要更新状态的优惠券");
            return;
        }
        for (CouponPO coupon : allCoupons) {
            Date startDate = coupon.getStartDate();
            Date endDate = coupon.getEndDate();
            if (startDate == null || endDate == null) {
                log.warn("优惠券[id={}]日期信息不完整，跳过状态更新", coupon.getId());
                continue;
            }
            int newStatus = getCouponStatus(startDate, endDate);
            if (coupon.getStatus() != newStatus) {
                coupon.setStatus(newStatus);
                coupon.setUpdateAt(new Date()); // 更新时间戳
                couponRepository.updateCoupon(coupon);
                log.info("优惠券[id={}]状态更新为：{}", coupon.getId(), newStatus);
            }
        }
        log.info("定时任务执行完毕：优惠券状态更新完成");
    }

    /*
    * 优化后每五分钟更新一次状态
    * */
    @Scheduled(cron = "0 0/5 * * * ?") // 每5分钟执行一次
    public void updateCouponStatus() {
        log.info("间隔定时任务开始执行：更新优惠券状态");
        Date now = new Date();
        List<CouponPO> needCheckCoupons = couponRepository.findNeedStatusUpdateCoupons(
                DateUtils.addMinutes(now, 5),  // 5分钟后
                now                            // 当前时间
        );
        if (CollectionUtils.isEmpty(needCheckCoupons)) {
            log.info("暂时没有需要更新状态的优惠券");
            return;
        }
        for (CouponPO coupon : needCheckCoupons) {
            int newStatus = getCouponStatus(coupon.getStartDate(), coupon.getEndDate());
            if (coupon.getStatus() != newStatus) {
                coupon.setStatus(newStatus);
                coupon.setUpdateAt(now);
                couponRepository.updateCoupon(coupon);
                log.info("将优惠券[id={}]状态更新为：{}", coupon.getId(), newStatus);
            }
        }
        log.info("定时任务执行完毕：共检查{}张优惠券，完成状态更新", needCheckCoupons.size());
    }

    //判断优惠券状态
    private Integer getCouponStatus(Date startDate, Date endDate) {
        LocalDateTime currentDateTime = LocalDateTime.now();
        String formattedCurrentTime=currentDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        log.info("当前时间:{}",formattedCurrentTime);
        LocalDateTime startDateTime=startDate.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        LocalDateTime endDateTime=endDate.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        if (currentDateTime.isBefore(startDateTime)) {
            return 0; // 在开始时间之前
        } else if (currentDateTime.isAfter(endDateTime)) {
            return 2; // 在结束时间之后
        } else {
            return 1; // 在时间范围内（包括等于开始时间或结束时间）
        }
    }
}


















